@fieldwangai/agentflow 0.1.110 → 0.1.113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4407,7 +4407,7 @@ function normalizeHtmlDisplayContent(content) {
4407
4407
  return text;
4408
4408
  }
4409
4409
 
4410
- function workspaceBodyPlaceholderNames(body) {
4410
+ export function workspaceBodyPlaceholderNames(body) {
4411
4411
  const names = new Set();
4412
4412
  const raw = String(body || "");
4413
4413
  raw.replace(/\$\{([A-Za-z_][A-Za-z0-9_-]*)\}/g, (_match, name) => {
@@ -4417,7 +4417,7 @@ function workspaceBodyPlaceholderNames(body) {
4417
4417
  return names;
4418
4418
  }
4419
4419
 
4420
- function workspaceRelevantInputValues(body, inputValues = {}) {
4420
+ export function workspaceRelevantInputValues(body, inputValues = {}) {
4421
4421
  const placeholders = workspaceBodyPlaceholderNames(body);
4422
4422
  if (!placeholders.size) return { values: inputValues || {}, placeholders };
4423
4423
  const values = {};
@@ -4427,6 +4427,17 @@ function workspaceRelevantInputValues(body, inputValues = {}) {
4427
4427
  return { values, placeholders };
4428
4428
  }
4429
4429
 
4430
+ export function workspaceAssertRequiredInputs(body, inputValues = {}, nodeId = "") {
4431
+ const placeholders = workspaceBodyPlaceholderNames(body);
4432
+ const missing = [...placeholders].filter((name) => (
4433
+ !Object.prototype.hasOwnProperty.call(inputValues || {}, name) ||
4434
+ !String(inputValues[name] ?? "").trim()
4435
+ ));
4436
+ if (!missing.length) return;
4437
+ const label = nodeId ? `Workspace node ${nodeId}` : "Workspace node";
4438
+ throw new Error(`${label} 缺少必需输入:${missing.join(", ")}。请连接对应输入槽或提供非空值。`);
4439
+ }
4440
+
4430
4441
  function workspaceDownstreamSlotKind(slot) {
4431
4442
  const name = String(slot?.name || "").trim().toLowerCase();
4432
4443
  const type = String(slot?.type || "").trim().toLowerCase();
@@ -5631,10 +5642,19 @@ function workspaceContextObjectFromText(text, baseCwd, scopedRoot) {
5631
5642
  };
5632
5643
  }
5633
5644
 
5645
+ function workspaceLooksLikeKnowledgePath(value) {
5646
+ const raw = String(value || "").trim();
5647
+ return Boolean(raw) &&
5648
+ raw.length <= 4096 &&
5649
+ !/[\r\n<>]/.test(raw) &&
5650
+ !/^```/.test(raw) &&
5651
+ !/^<!doctype/i.test(raw);
5652
+ }
5653
+
5634
5654
  function workspaceKnowledgeSourceFromObject(source = {}, baseCwd = "", scopedRoot = "") {
5635
5655
  if (!source || typeof source !== "object" || Array.isArray(source)) return null;
5636
5656
  const rawPath = String(source.path || source.repoPath || source.cwd || source.workspaceRoot || "").trim();
5637
- if (!rawPath) return null;
5657
+ if (!workspaceLooksLikeKnowledgePath(rawPath)) return null;
5638
5658
  const resolvedPath = workspaceResolvePath(baseCwd || scopedRoot, rawPath) || rawPath;
5639
5659
  return {
5640
5660
  id: String(source.id || source.mountPath || source.label || path.basename(resolvedPath) || "").trim(),
@@ -5650,7 +5670,7 @@ function workspaceKnowledgeSourceFromObject(source = {}, baseCwd = "", scopedRoo
5650
5670
  };
5651
5671
  }
5652
5672
 
5653
- function workspaceKnowledgeSourcesFromText(text, baseCwd = "", scopedRoot = "") {
5673
+ export function workspaceKnowledgeSourcesFromText(text, baseCwd = "", scopedRoot = "") {
5654
5674
  const raw = String(text || "").trim();
5655
5675
  if (!raw) return [];
5656
5676
  const parsed = parseJsonText(raw, null);
@@ -5664,6 +5684,7 @@ function workspaceKnowledgeSourcesFromText(text, baseCwd = "", scopedRoot = "")
5664
5684
  .map((source) => workspaceKnowledgeSourceFromObject(source, baseCwd, scopedRoot))
5665
5685
  .filter(Boolean);
5666
5686
  }
5687
+ if (!workspaceLooksLikeKnowledgePath(raw)) return [];
5667
5688
  const resolved = workspaceResolvePath(baseCwd || scopedRoot, raw) || raw;
5668
5689
  return [{
5669
5690
  id: path.basename(resolved) || "knowledge",
@@ -6155,13 +6176,49 @@ function workspaceCreateNodeRunPackage(runTmpRoot, nodeId, { scopedRoot, cwd = "
6155
6176
  };
6156
6177
  }
6157
6178
 
6158
- function workspaceMaterializeNodeInputFiles(nodeRunDir, workspaceRoot, inputValues = {}) {
6179
+ const WORKSPACE_INLINE_INPUT_FILE_THRESHOLD = 4096;
6180
+
6181
+ function workspaceInlineInputExtension(value) {
6182
+ const text = String(value || "").trim();
6183
+ if (/^(?:<!doctype\s+html|<html\b)/i.test(text)) return ".html";
6184
+ if (/^[\[{]/.test(text)) {
6185
+ try {
6186
+ JSON.parse(text);
6187
+ return ".json";
6188
+ } catch {}
6189
+ }
6190
+ if (/^(?:#{1,6}\s|---\s*$)/m.test(text)) return ".md";
6191
+ return ".txt";
6192
+ }
6193
+
6194
+ export function workspaceMaterializeNodeInputFiles(nodeRunDir, workspaceRoot, inputValues = {}) {
6159
6195
  const values = {};
6160
6196
  const mounts = {};
6161
6197
  for (const [name, value] of Object.entries(inputValues || {})) {
6162
6198
  const slotName = String(name || "").trim();
6163
6199
  if (!slotName) continue;
6164
6200
  const rel = workspaceInputFileRelPath(value);
6201
+ const inlineText = String(value ?? "");
6202
+ if (!rel && inlineText.length >= WORKSPACE_INLINE_INPUT_FILE_THRESHOLD) {
6203
+ const extension = workspaceInlineInputExtension(inlineText);
6204
+ const fileName = `${workspaceSanitizeTmpSegment(slotName, "input")}${extension}`;
6205
+ const mountedRel = path.join("inputs", workspaceSanitizeTmpSegment(slotName, "input"), fileName);
6206
+ const dest = path.resolve(nodeRunDir, mountedRel);
6207
+ const nodeRunWithSep = nodeRunDir.endsWith(path.sep) ? nodeRunDir : `${nodeRunDir}${path.sep}`;
6208
+ if (dest !== nodeRunDir && !dest.startsWith(nodeRunWithSep)) continue;
6209
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
6210
+ fs.writeFileSync(dest, inlineText, "utf-8");
6211
+ const mounted = mountedRel.split(path.sep).join(path.posix.sep);
6212
+ values[slotName] = mounted;
6213
+ mounts[slotName] = {
6214
+ source: `inline:${slotName}`,
6215
+ mounted,
6216
+ bytes: Buffer.byteLength(inlineText, "utf-8"),
6217
+ sha256: crypto.createHash("sha256").update(inlineText, "utf-8").digest("hex"),
6218
+ inline: true,
6219
+ };
6220
+ continue;
6221
+ }
6165
6222
  if (!rel) continue;
6166
6223
  const src = path.resolve(workspaceRoot, rel);
6167
6224
  const rootWithSep = workspaceRoot.endsWith(path.sep) ? workspaceRoot : `${workspaceRoot}${path.sep}`;
@@ -7038,6 +7095,7 @@ async function runWorkspaceGraph(root, scopedRoot, payload, userCtx = {}, opts =
7038
7095
  const prepareStartedAt = Date.now();
7039
7096
  const inputValues = workspaceInputValues(graph, nodeId, outputs, scopedRoot);
7040
7097
  const relevantInputs = workspaceRelevantInputValues(instance.body || "", inputValues);
7098
+ workspaceAssertRequiredInputs(instance.body || "", inputValues, nodeId);
7041
7099
  const upstreamText = workspaceTaskUpstreamText(graph, nodeId, outputs, relevantInputs.placeholders, scopedRoot);
7042
7100
  const upstreamSkillBlocks = workspaceUpstreamSkillBlocks(graph, nodeId, outputs);
7043
7101
  const ownSkillBlock = isContextRunNode ? loadSkillsBlockForKeys(selectedSkillKeysFromConfigSlots(instance)) : "";